#include <vector>
#include <iostream>
#include <fstream>
#include "parser.h"
#include "holder.h"
#include "date.h"
#include "time.h"
#include "feature_extractor.h"
#include "decide.h"

using namespace std;
using namespace stock_trade;

void testParserSituation(const Stock& stock, const Date& date)
{
    vector<Situation> vecSituation = Parser::ParseSituation(stock, date);
    //vector<Situation> vecSituation = Parser::ParseSituation("../data/buy_sell/sz000982/2012-12-04/buy_sell");
    //vector<Situation> vecSituation = Parser::ParseSituation("../data/buy_sell/sz300103/2012-12-04/buy_sell");
    //vector<Situation> vecSituation = Parser::ParseSituation("../data/buy_sell/sz002377/2012-12-04/buy_sell");
    int len = vecSituation.size();
    for (int i = 0; i < len; i++)
    {
        //cout << vecSituation[i].GetQuantityPercent() << "\t" << vecSituation[i].GetPowerPercent() << endl;
        float quantityPercent = vecSituation[i].GetQuantityPercent();
        float powerPercent = vecSituation[i].GetPowerPercent();
        if (quantityPercent > 2 && powerPercent > 1.5)
            cout << "buy:" << vecSituation[i].stock.code 
                << "\t" << vecSituation[i].stock.name
                << "\t" << vecSituation[i].date 
                << "\t" << vecSituation[i].time 
                << "\t" << vecSituation[i].nowPrice 
                << "\t" << quantityPercent
                << "\t" << powerPercent
                << endl;
        if (quantityPercent < 0.6)
            cout << "sell:" << vecSituation[i].stock.code 
                << "\t" << vecSituation[i].stock.name
                << "\t" << vecSituation[i].date 
                << "\t" << vecSituation[i].time 
                << "\t" << vecSituation[i].nowPrice 
                << "\t" << quantityPercent
                << "\t" << powerPercent
                << endl;
    }
}

void testParserTransaction(const Stock& stock, const Date& date)
{
    vector<Transaction> vecTransaction = Parser::ParseTransaction(stock, date);
    int len = vecTransaction.size();
    for (int i = 0; i < len; i++)
    {
        //cout << vecTransaction[i].GetQuantityPercent() << "\t" << vecTransaction[i].GetPowerPercent() << endl;
        cout << "buy:" << vecTransaction[i].stock.code 
            << "\t" << vecTransaction[i].stock.name
            << "\t" << vecTransaction[i].date 
            << "\t" << vecTransaction[i].time 
            << "\t" << vecTransaction[i].price 
            << "\t" << vecTransaction[i].number
            << "\t" << vecTransaction[i].type
            << "\t" << vecTransaction[i].action
            << "\t" << vecTransaction[i].status
            << endl;
        /*float quantityPercent = vecTransaction[i].GetQuantityPercent();
        float powerPercent = vecTransaction[i].GetPowerPercent();
        if (quantityPercent > 2 && powerPercent > 1.5)
            cout << "buy:" << vecTransaction[i].stock.code 
                << "\t" << vecTransaction[i].stock.name
                << "\t" << vecTransaction[i].date 
                << "\t" << vecTransaction[i].time 
                << "\t" << vecTransaction[i].nowPrice 
                << "\t" << quantityPercent
                << "\t" << powerPercent
                << endl;
        if (quantityPercent < 0.6)
            cout << "sell:" << vecTransaction[i].stock.code 
                << "\t" << vecTransaction[i].stock.name
                << "\t" << vecTransaction[i].date 
                << "\t" << vecTransaction[i].time 
                << "\t" << vecTransaction[i].nowPrice 
                << "\t" << quantityPercent
                << "\t" << powerPercent
                << endl;
                */
    }
}

void testGetLongTimePrices(const string& fileName, Date date, Time time)
{
    //vector<Situation> vecSituation = Parser::ParseSituation(fileName);
    Stock stock("sh600612", "sh600612");
    vector<Situation> vecSituation = Parser::ParserLongTimeSituation(stock, date, 1);
    vector<float> max_min = FeatureExtractor::GetLongTimePrices(vecSituation, date, time);
}

void testDecision(Stock stock, Holder& holder, Date startDate, Date endDate, Time startTime, Time endTime, float buyScore, float sellScore)
{
    for (Date date = startDate; date <= endDate; ++date)
    {
        vector<Transaction> vecTransaction = Parser::ParseTransaction(stock, date);
        vector<Situation> vecSituation = Parser::ParseSituation(stock, date);
        vector<Transaction> vecLongTimeTransaction = Parser::ParserLongTimeTransaction(stock, date, 2);
        vector<Situation> vecLongTimeSituation = Parser::ParserLongTimeSituation(stock, date, 7);

        for (Time time = startTime; time <= endTime; ++time)
        {
            vector<float> features = FeatureExtractor::MergeFeature(vecSituation, vecTransaction, vecLongTimeSituation, vecLongTimeTransaction, date, time);
            //cout << features[0] << "\t" << features[1] << "\t" << features[2] << "\t" << features[3] << endl;
            float score = 0;
            Transaction t = Decide::decide(features, stock, date, time, buyScore, sellScore, holder, score);
            bool returnValue = holder.process(t);
            //if (returnValue)
            //    cout << t.date << " " << t.time << " " << t.action 
            //        << " " << t.stock.name << " " << t.number << " " << t.price << endl;
        }
        cout << date << "\t" << holder.GetCurrentValue(date, endTime) << endl;
    }
    cout << endDate << "\t" << holder.GetCurrentValue(endDate, endTime) << endl;
}

void testAllDecision(vector<Stock> vecStock, Holder& holder, Date startDate, Date endDate, Time startTime, Time endTime, float buyScore, float sellScore)
{
    for (Date date = startDate; date <= endDate; ++date)
    {
        map<string, vector<Transaction> > mapTransaction;
        map<string, vector<Situation> > mapSituation;
        map<string, vector<Transaction> > mapLongTimeTransaction;
        map<string, vector<Situation> > mapLongTimeSituation;
        for (vector<Stock>::iterator i = vecStock.begin(); i != vecStock.end(); ++i)
        {
            vector<Transaction> vecTransaction = Parser::ParseTransaction(*i, date);
            vector<Situation> vecSituation = Parser::ParseSituation(*i, date);
            vector<Transaction> vecLongTimeTransaction = Parser::ParserLongTimeTransaction(*i, date, 2);
            vector<Situation> vecLongTimeSituation = Parser::ParserLongTimeSituation(*i, date, 7);
            mapTransaction[i->code] = vecTransaction;
            mapSituation[i->code] = vecSituation;
            mapLongTimeTransaction[i->code] = vecLongTimeTransaction;
            mapLongTimeSituation[i->code] = vecLongTimeSituation;
        }
        for (Time time = startTime; time <= endTime; ++time)
        {
            vector<vector<float> > allFeatures;
            for (vector<Stock>::iterator i = vecStock.begin(); i != vecStock.end(); ++i)
            {
                vector<float> features = FeatureExtractor::MergeFeature(mapSituation[i->code], mapTransaction[i->code], 
                                                                        mapLongTimeSituation[i->code], mapLongTimeTransaction[i->code], date, time);
                //cout << features[0] << "\t" << features[1] << "\t" << features[2] << "\t" << features[3] << endl;
                allFeatures.push_back(features);
            }

            pair<vector<pair<Transaction, float> >, vector<pair<Transaction, float> > > transactions = Decide::decideAll(allFeatures, vecStock, date, time, buyScore, sellScore, holder);
            for (vector<pair<Transaction, float> >::iterator i = transactions.first.begin(); i != transactions.first.end(); ++i)
                bool returnValue = holder.process(i->first);
            for (vector<pair<Transaction, float> >::iterator i = transactions.second.begin(); i != transactions.second.end(); ++i)
                bool returnValue = holder.process(i->first);
                //if (returnValue)
                //    cout << t.date << " " << t.time << " " << t.action 
                //        << " " << t.stock.name << " " << t.number << " " << t.price << endl;
        }
        cout << date << "\t" << holder.GetCurrentValue(date, endTime) << endl;
    }
    cout << endDate << "\t" << holder.GetCurrentValue(endDate, endTime) << endl;
}

int main(int argc, char* argv[])
{
    //string fileName = "../data/buy_sell/sh600612/2012-12-04/buy_sell";
    //Date date(2012,12,5);
    //Time time(15,5,5);
    //testGetLongTimePrices(fileName, date, time);
    //return 0;

//    testParserTransaction(argv[1]);
//    testParserSituation(argv[1]);
    //float buyScore = 50000;
    //float sellScore = -17000;
    float buyScore = 15000;
    float sellScore = -15000;
    Holder holder;
    holder.cash = 100000;
    holder.validCash = 100000;

    vector<Stock> vecStock = Parser::readAllStock("../conf/stock_list");
    //Stock stock("sz002507", "sz002507");
    //vector<Stock> vecStock;
    //vecStock.push_back(stock);
    //Time startTime(14, 59, 5);

    //Stock stock("sz300103", "达刚路机");
    //Date startDate(2012, 12, 4);
    //Date endDate(2012, 12, 31);
    Time startTime(9, 30, 45);
    //Time endTime(11, 30, 5);
    Date startDate(2013, 8, 2);
    Date endDate(2013, 8, 2);
    //Date startDate(2013, 2, 18);
    //Date endDate(2012, 12, 31);
    //Time startTime(13, 0, 5);
    Time endTime(15, 0, 5);
    //testDecision(stock, holder, startDate, endDate, startTime, endTime);
    testAllDecision(vecStock, holder, startDate, endDate, startTime, endTime, buyScore, sellScore);
    //holder.PrintFailedLog();
    return 0;
}
